﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using TmU220PrintHelperV2d0.Entity;
using ZhangLogSysV1d0;
using System.Drawing.Drawing2D;
using TmU220PrintHelperV2d0.Service;

namespace TmU220PrintHelperV2d0.ControlUi
{
    public partial class PrintTempletRowDisplay : UserControl
    {
        public PrintTempletRowDisplay()
        {
            InitializeComponent();
            Index = 0;
            IsSelected = false;
            ContentAreaType = AreaTypeV2d0.Header;
            //测试数据
            var printTempletRow = GetTestData();
            Init(printTempletRow);
        }
        public PrintTempletRowDisplay(PrintTempletRowV2d0 printTempletRow)
        {
            InitializeComponent();
            PrintTempletRow = printTempletRow;
            Index = PrintTempletRow.RowIndex;
            IsSelected = false;
            ContentAreaType = PrintTempletRow.AreaType;
            Init(PrintTempletRow);
        }
        public PrintTempletRowV2d0 GetTestData()
        {
            PrintTempletRowV2d0 templetRow = new PrintTempletRowV2d0();
            PrintTempletElementV2d0 templetElement = new PrintTempletElementV2d0();
            templetRow.TempletElementList.Add(templetElement);
            templetElement = new PrintTempletElementV2d0();
            templetElement.FontSize = 20;
            templetElement.HorizontalAlign = "Right";
            templetElement.FontColor = "Red";
            templetRow.TempletElementList.Add(templetElement);
            return templetRow;
        }
        private PrintTempletRowV2d0 PrintTempletRow { get; set; }
        public int Index { get; set; }
        public bool IsSelected { get; set; }
        public AreaTypeV2d0 ContentAreaType { get; set; }
        /// <summary>
        /// 面板选中事件
        /// </summary>
        public event EventHandler<PrintTempletRowV2d0> PanelSelectedEvent = null;
        public void Init(PrintTempletRowV2d0 printTempletRow)
        {
            try
            {
                PrintTempletRow = printTempletRow;
                IsSelected = false;
                Index = PrintTempletRow.RowIndex;
                ContentAreaType = PrintTempletRow.AreaType;
                this.Height = GetSuitableHeight(printTempletRow);
                this.Refresh();
            }
            catch(Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }
        /// <summary>
        /// 得到合适的图像高度
        /// </summary>
        /// <returns></returns>
        public static int GetSuitableHeight(PrintTempletRowV2d0 printTempletRow,string deviceType="TM-U220")
        {
            int height = 0;
            Bitmap tmpBitmap = new Bitmap(32, 32);
            // 字号与高度的比例
            const float _lineHeightProportion = 1.45f;
            //76打印纸扣去两边内距实际可打的宽度为63.5
            float validAreaWidth = 396;
            if (deviceType == "TM-U220") validAreaWidth = 396;
            else if (deviceType == "XP-Q200") validAreaWidth = 570;
            using (Graphics tmpGrapics = Graphics.FromImage(tmpBitmap))
            {
                float textHeightMax = 0;
                 foreach (var element in printTempletRow.TempletElementList)
                {
                    //Font tmpFont = new Font(element.FontName, element.FontSize, FontStyle.Regular);
                    int fontSize = element.FontSize;
                    string content = element.ContentText;
                    int rowNum = 0;
                    float contentWidth = validAreaWidth;
                    string newContent = HotchPotchV2d0.ContentWarp(content, fontSize, contentWidth, out rowNum,deviceType);
                    float elementHeight = element.FontSize * _lineHeightProportion* rowNum;
                    if (elementHeight > textHeightMax) textHeightMax = elementHeight;
                }
                height = (int)(textHeightMax / 8 + 1) * 8;
            }
            tmpBitmap.Dispose();
            tmpBitmap = null;
            return height;
        }
        /// <summary>
        /// 计算文本高度和宽度
        /// </summary>
        /// <param name="g"></param>
        /// <param name="font"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public static SizeF CalTextWidthHeight(Graphics g, Font font, string text)
        {
            StringFormat sf = StringFormat.GenericTypographic;
            sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
            SizeF s = g.MeasureString(text, font, 0, sf);
            return s;
        }
        /// <summary>
        /// 绘制header和footer模板行到画板
        /// </summary>
        public static void DrawHeaderFooterRowOnGraphics(PrintTempletRowV2d0 printTempletRow,Graphics drawingGraphics,int canvasWidth,int canvasHeight,string deviceType="TM-U220")
        {
            try
            {
                if(drawingGraphics!=null)
                {
                    //先绘制在临时位图上，最后再绘制到Panel上
                    using (Bitmap tmpBitmap = new Bitmap(canvasWidth, canvasHeight))
                    {
                        Graphics bitmapGraphics = Graphics.FromImage(tmpBitmap);
                        bitmapGraphics.Clear(Color.White);
                        //对于明细行，存在换行的情况，所以将左中右元素内容依次排列，进行整体打印
                        //对于非明细行，仅在一行内进行打印，所以制，左对齐元素，居中元素，右对齐元素（相对于一行的，左对齐，居中，右对齐）
                        if (printTempletRow.AreaType == AreaTypeV2d0.Detail)
                        {
                            //左对齐元素
                            string contentOfElements = "";
                            DrawElementsOfDetailOnGraphics(printTempletRow.TempletElementList, bitmapGraphics, tmpBitmap.Width, tmpBitmap.Height,deviceType);
                            drawingGraphics.DrawImage(tmpBitmap, 0, 0);

                        }
                        else
                        {
                            //左对齐元素
                            var elementListOfAlignLeft = printTempletRow.TempletElementList.FindAll(x => x.HorizontalAlign == "Left");
                            if (elementListOfAlignLeft.Count > 0) DrawElementsOfHeaderFooterOnGraphics(elementListOfAlignLeft, bitmapGraphics, tmpBitmap.Width, tmpBitmap.Height);
                            //居中元素的绘制比较特殊一些
                            var elementListOfAlignCenter = printTempletRow.TempletElementList.FindAll(x => x.HorizontalAlign == "Center");
                            if (elementListOfAlignCenter.Count > 0) DrawElementsOfHeaderFooterOnGraphics(elementListOfAlignCenter, bitmapGraphics, tmpBitmap.Width, tmpBitmap.Height);
                            //右对齐元素的绘制方法和左对齐元素的方法相同
                            var elementListOfAlignRight = printTempletRow.TempletElementList.FindAll(x => x.HorizontalAlign == "Right");
                            if (elementListOfAlignRight.Count > 0) DrawElementsOfHeaderFooterOnGraphics(elementListOfAlignRight, bitmapGraphics, tmpBitmap.Width, tmpBitmap.Height);
                            drawingGraphics.DrawImage(tmpBitmap, 0, 0);
                        }
                        bitmapGraphics.Dispose();
                        bitmapGraphics = null;
                    }
                }
            }
            catch(Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }

        /// <summary>
        /// 绘制元素到画板
        /// </summary>
        /// <param name="printTempletElementList"></param>
        /// <param name="canvas"></param>
        /// <param name="canvasWidth"></param>
        /// <param name="canvasHeight"></param>
        public static void DrawElementsOfHeaderFooterOnGraphics(List<PrintTempletElementV2d0> printTempletElementList, Graphics canvas, int canvasWidth, int canvasHeight)
        {
            try
            {
                float elementsWidthTotal = 0;
                foreach (var element in printTempletElementList) elementsWidthTotal += GetElementWidth(canvas, element);
                string horizontalAlign = printTempletElementList[0].HorizontalAlign;
                //计算的绘制的左边起始位置
                float borderLeftX = 0;
                if (horizontalAlign == "Left") borderLeftX = 0;
                else if (horizontalAlign == "Right") borderLeftX = canvasWidth- elementsWidthTotal-24;
                else if(horizontalAlign == "Center") borderLeftX = (canvasWidth - elementsWidthTotal)/2;
                float drawedWidth = 0;
                foreach (var element in printTempletElementList)
                {
                    drawedWidth = DrawTextOfElementToGraphics(canvas, canvasWidth, canvasHeight, element, borderLeftX);
                    borderLeftX += drawedWidth;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }
        /// <summary>
        /// 用于绘制明细行，，第三个元素全部绘制（多行）在第一个元素右边
        /// 
        /// </summary>
        /// <param name="printTempletElementList"></param>
        /// <param name="canvas"></param>
        /// <param name="canvasWidth"></param>
        /// <param name="canvasHeight"></param>
        public static void DrawElementsOfDetailOnGraphics(List<PrintTempletElementV2d0> printTempletElementList, Graphics canvas, int canvasWidth, int canvasHeight,string deviceType="TM-U220")
        {
            try
            {
               //计算的绘制的左边起始位置
                float borderLeftX = 0;
                float drawedWidth = 0;

                // 绘制第一个元素
                if (printTempletElementList.Count > 0)
                {
                    drawedWidth = DrawTextOfElementToGraphics(canvas, canvasWidth, canvasHeight, printTempletElementList[0], borderLeftX);
                }
                borderLeftX += drawedWidth;
                // 绘制第二个元素
                if (printTempletElementList.Count > 1)
                {
                    DrawTextOfRowToGraphics(canvas, canvasWidth, canvasHeight, printTempletElementList[1], borderLeftX, deviceType);
                }
                borderLeftX += drawedWidth;
                // 绘制第三个元素
                if (printTempletElementList.Count > 2)
                {
                    DrawTextOfRowToGraphics(canvas, canvasWidth, canvasHeight, printTempletElementList[2], borderLeftX, deviceType);
                }


            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }
        public void ReleaseCustomResource()
        {
            //--------
        }
        /// <summary>
        ///         /// <summary>
        /// 绘制文本到画板
        /// </summary>
        /// </summary>
        /// <param name="drawingGraphics"></param>
        /// <param name="canvasWidth"></param>
        /// <param name="canvasHeight"></param>
        /// <param name="printTempletElement"></param>
        /// <param name="leftBorderX">绘制的水平起始位置</param>
        /// <returns>已绘制元素的宽度（像素）</returns>
        public static float DrawTextOfElementToGraphics(Graphics drawingGraphics, int canvasWidth, int canvasHeight, PrintTempletElementV2d0 printTempletElement,float leftBorderX)
        {
            float drawedWidth = 0;

            try
            {
                if (drawingGraphics != null)
                {
                    string contentText = printTempletElement.ContentText;
                    string verticalAlign = printTempletElement.VerticalAlign;
                    string horizontalAlign = printTempletElement.HorizontalAlign;
                    string fontName = printTempletElement.FontName;
                    int fontSize = printTempletElement.FontSize;
                    string fontColor = printTempletElement.FontColor;
                    Font drawFont = new Font(fontName, fontSize, FontStyle.Regular);
                    FontStyle fStyle = FontStyle.Regular;
                    if (printTempletElement.IsBold) fStyle = fStyle | FontStyle.Bold;
                    if (printTempletElement.IsUnderLine) fStyle = fStyle | FontStyle.Underline;
                    drawFont = new Font(fontName, fontSize, fStyle);
                    Brush printBrush = new SolidBrush(Color.FromName(fontColor));
                    SizeF stringSize = drawingGraphics.MeasureString(contentText, drawFont);
                    float stringWidth = stringSize.Width;
                    float stringHeight = stringSize.Height;
                    drawedWidth = stringWidth;
                    //水平起始位置
                    float startX = leftBorderX;
                    //垂直起始位置
                    float startY = 0;

                    drawingGraphics.DrawString(contentText, drawFont, printBrush, startX, startY);
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return drawedWidth;
        }
        /// <summary>
        /// 绘制打印行的文本（三个元素的内容连接到一起）到画板
        /// </summary>
        /// <param name="drawingGraphics"></param>
        /// <param name="canvasWidth"></param>
        /// <param name="canvasHeight"></param>
        /// <param name="printTempletElement"></param>
        /// <param name="leftBorderX"></param>
        /// <returns></returns>
        public static float DrawTextOfRowToGraphics(Graphics drawingGraphics, int canvasWidth, int canvasHeight, PrintTempletElementV2d0 printTempletElement, float leftBorderX,string deviceType="TM-U220")
        {
            float drawedWidth = 0;
            const float _lineHeightProportion = 1.5f;
            try
            {
                if (drawingGraphics != null)
                {
                    string contentText = printTempletElement.ContentText;
                    string verticalAlign = printTempletElement.VerticalAlign;
                    string horizontalAlign = printTempletElement.HorizontalAlign;
                    string fontName = printTempletElement.FontName;
                    fontName = "Arial";
                    int fontSize = printTempletElement.FontSize;
                    string fontColor = printTempletElement.FontColor;
                    Font drawFont = new Font(fontName, fontSize, FontStyle.Regular);
                    FontStyle fStyle = FontStyle.Regular;
                    if (printTempletElement.IsBold) fStyle = fStyle | FontStyle.Bold;
                    if (printTempletElement.IsUnderLine) fStyle = fStyle | FontStyle.Underline;
                    drawFont = new Font(fontName, fontSize, fStyle);
                    Brush printBrush = new SolidBrush(Color.FromName(fontColor));
                    SizeF stringSize = drawingGraphics.MeasureString(contentText, drawFont);
                    float stringWidth = stringSize.Width;
                    float stringHeight = stringSize.Height;
                    drawedWidth = stringWidth;
                    //水平起始位置
                    float startX = leftBorderX;
                    //垂直起始位置
                    float startY = 0;
                     
                    const double PaperWidth76 = 63.5;
                    // int _paperWidth = Convert.ToInt32(Math.Ceiling(PaperWidth76 * 3.937));
                    int rowNum = 0;
                    //float contentWidth = _paperWidth;
                    float contentWidth = canvasWidth;
                    // 处理文本折行
                    string newContent = HotchPotchV2d0.ContentWarp(contentText, fontSize, contentWidth, out rowNum, deviceType);
                    //数量这个多留点5个像素的空白
                    leftBorderX += 5;

                    var point = new PointF(leftBorderX, 0);
                    float contentHeight = (int)fontSize * _lineHeightProportion * rowNum;
                    SizeF contentSizeF = HotchPotchV2d0.GetStringSizeFWithGdi(newContent, fontSize);
                    contentHeight = contentSizeF.Height;
                    

                    var size = new SizeF(contentWidth- leftBorderX, (int)fontSize * _lineHeightProportion * rowNum);
                    var layoutRectangle = new RectangleF(point, size);

                    var format = new StringFormat
                    {
                        Alignment = StringAlignment.Near,
                        FormatFlags = StringFormatFlags.NoWrap
                    };
                    drawingGraphics.DrawString(newContent, drawFont, printBrush, layoutRectangle, format);
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return drawedWidth;
        }
        /// <summary>
        /// 得到元素在画板上的宽度（像素）
        /// </summary>
        /// <param name="drawingGraphics"></param>
        /// <param name="printTempletElement"></param>
        /// <returns>元素宽度</returns>
        public static float GetElementWidth(Graphics drawingGraphics, PrintTempletElementV2d0 printTempletElement)
        {
            float stringWidth = 0;
            try
            {
                if (drawingGraphics != null)
                {
                    string contentText = printTempletElement.ContentText;
                    string fontName = printTempletElement.FontName;
                    int fontSize = printTempletElement.FontSize;
                    Font drawFont = new Font(fontName, fontSize, FontStyle.Regular);
                    StringFormat sf = StringFormat.GenericTypographic;
                    sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
                    SizeF stringSize = drawingGraphics.MeasureString(contentText, drawFont,0,sf);
                    stringWidth = stringSize.Width;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return stringWidth;
        }

        private void PrintTempletItemDisplay_Load(object sender, EventArgs e)
        {
            //-----
            this.Height = GetSuitableHeight(PrintTempletRow);
        }
        
        private void pictureBoxDraw_Paint(object sender, PaintEventArgs e)
        {   
            Graphics currGraphics = e.Graphics;
            DrawHeaderFooterRowOnGraphics(PrintTempletRow, currGraphics,this.panelDraw.Width, this.panelDraw.Height);
            //绘制选中边框
            Rectangle borderRectangle = this.ClientRectangle;
            if (IsSelected)
            {
                ControlPaint.DrawBorder(e.Graphics, borderRectangle,
                Color.Red, 2, ButtonBorderStyle.Solid, //左边
                Color.Red, 2, ButtonBorderStyle.Solid, //上边
                Color.Red, 2, ButtonBorderStyle.Solid, //右边
                Color.Red, 2, ButtonBorderStyle.Solid);//底边
            }
            else
            {
                ControlPaint.DrawBorder(e.Graphics, borderRectangle,
                Color.Black, 1, ButtonBorderStyle.Solid, //左边
                Color.Black, 1, ButtonBorderStyle.Solid, //上边
                Color.Black, 1, ButtonBorderStyle.Solid, //右边
                Color.Black, 1, ButtonBorderStyle.Solid);//底边
            }
        }

        private void panelDraw_Click(object sender, EventArgs e)
        {
            IsSelected = true;
            //发出被选中事件
            if (PanelSelectedEvent != null) PanelSelectedEvent(this, PrintTempletRow);
            this.Refresh();
        }
    }
    
}
